import 'dart:core';
import 'dart:collection'; // *** 新增：导入 dart:collection 以使用 IterableBase ***

// 问题五：自定义Iterator实现

// 解释：
// moveNext()和current的关系：
// 1. moveNext()准备下一个元素并返回是否有更多元素
// 2. current获取当前元素
// 调用顺序：必须先调用moveNext()再访问current

// 自定义迭代器示例：生成斐波那契数列
class FibonacciSequence extends IterableBase<int> {
  final int count; // 需要生成的斐波那契数列项数

  // 构造函数，接收要生成的项数
  FibonacciSequence(this.count) {
    // 可以添加校验，确保 count 不为负数
    if (count < 0) {
      throw ArgumentError('项数不能为负数');
    }
  }

  // 实现 Iterable 接口的 iterator getter，返回自定义的迭代器
  // IterableBase 会使用这个 iterator 来实现其他 Iterable 方法
  @override
  Iterator<int> get iterator => FibonacciIterator(count);
}

// 自定义斐波那契数列迭代器
class FibonacciIterator implements Iterator<int> {
  final int maxCount; // 最大项数
  int _currentValue = 0; // 当前斐波那契数 (对应 current getter)
  int _nextValue = 1; // 下一个斐波那契数 (用于计算)
  int _currentIndex = 0; // 当前迭代到的索引 (从 0 开始)

  // 迭代器构造函数
  FibonacciIterator(this.maxCount);

  // 实现 Iterator 接口的 current getter
  @override
  int get current => _currentValue;

  // 实现 Iterator 接口的 moveNext 方法
  @override
  bool moveNext() {
    // 如果已经迭代完成指定的项数，返回 false
    if (_currentIndex >= maxCount) {
      return false;
    }

    // 根据索引计算当前的斐波那契数
    if (_currentIndex == 0) {
      // 第一个数是 0
      _currentValue = 0;
    } else if (_currentIndex == 1) {
      // 第二个数是 1
      _currentValue = 1;
      // 初始化下一个值为 1 (因为 0 + 1 = 1)
      _nextValue = 1;
    } else {
      // 计算下一个斐波那契数
      // F(n) = F(n-1) + F(n-2)
      // 临时保存当前的 _currentValue (即 F(n-1))
      final temp = _currentValue;
      // 更新 _currentValue 为之前的 _nextValue (即 F(n))
      _currentValue = _nextValue;
      // 计算新的 _nextValue (即 F(n+1))
      _nextValue = temp + _currentValue;
    }

    // 索引加一，为下一次迭代做准备
    _currentIndex++;
    // 成功移动到下一个元素，返回 true
    return true;
  }
}

void main() {
  // 创建斐波那契序列实例，指定生成 10 项
  final fib = FibonacciSequence(10);

  // 使用 for-in 循环 (会自动调用 iterator 和 moveNext/current)
  print('斐波那契数列 (前 ${fib.count} 项):');
  for (final num in fib) {
    print(num); // 依次输出 0, 1, 1, 2, 3, 5, 8, 13, 21, 34
  }

  // 手动使用迭代器，演示调用顺序
  print('\n手动使用迭代器:');
  final iterator = fib.iterator;
  // 必须先调用 moveNext()
  while (iterator.moveNext()) {
    // 只有在 moveNext() 返回 true 后，才能安全访问 current
    print('当前元素: ${iterator.current}');
  }
  print('迭代结束');

  // 测试边界情况
  print('\n测试 0 项:');
  final fib0 = FibonacciSequence(0);
  for (final num in fib0) {
    print(num); // 不会输出任何内容
  }
  print('(无输出)');

  print('\n测试 1 项:');
  final fib1 = FibonacciSequence(1);
  for (final num in fib1) {
    print(num); // 输出 0
  }

  // 因为继承了 IterableBase，现在可以使用 Iterable 的其他方法了！
  print('\n测试 Iterable 方法:');
  final fib5 = FibonacciSequence(5); // 0, 1, 1, 2, 3
  print('前 5 项: ${fib5.toList()}'); // 使用 toList()
  print('包含 3 吗? ${fib5.contains(3)}'); // 使用 contains()
  print('第一个元素: ${fib5.first}'); // 使用 first
  print('最后一个元素: ${fib5.last}'); // 使用 last
  print('长度: ${fib5.length}'); // 使用 length
  print('大于 1 的元素: ${fib5.where((n) => n > 1).toList()}'); // 使用 where()
}
